#define _CRT_SECURE_NO_WARNINGS 1


		《 Linux_23_重定向_修改文件描述符 》


	< 1.被打开的文件 >
前提条件，这个文件已经被(进程)打开了！！！

而我们电脑中存在着非常多的文件，这些文件只有少量的文件是被打开的。
我们要如何找到这个文件呢？
找文件 -> 磁盘 -> 通过文件路径 + 文件名。(难道我们遍历吗？这也太慢了)


	< 2.没有被打开的文件 >
没有被打开的文件在哪里存放着的呢？
在磁盘中存放：【磁盘文件】  --> 【文件如何存储？】

————————————————————————————————————————————————


		《 重定向 '>' 》

#include <stdio.h>

int main()
{
    fprintf(stdout, "fo stdout!\n");	//向标准 → 输出
    fprintf(stderr, "fo err!\n");		//向标准 → 错误

    return 0;
}

[a@192 23]$ gcc test_stderr.c
- rwxrwxr - x. 1 a a 8496 Apr 29 08:57 a.out
[a@192 23]$ . / a.out
结果：
fo stdout!
fo err!

		《 重定向 》
  '>' 标准输出重定向
  '>' 这个只更改 1 号 fd 里的内容，err 是 2 号文件描述符内容，不会修改，所以 err 还是向标准输出打印。
 
[a@192 23]$ ./a.out > log.txt			//重定向为：向文件里打印，
fo err!								//但是标准错误依然 向显示器打印。
[a@192 23]$ cat log.txt				
fo stdout!

结论：
这样就可以通过 '>' 重定向，把 正确信息 与 错误信息 在文件层面上分开了


————————————————————————————————————————————————


 分离：《 正确与错误信息 》

#include <stdio.h>

int main()
{
    fprintf(stdout, "fo stdout!\n");
    fprintf(stdout, "fo stdout!\n");
    fprintf(stderr, "fo err!\n");
    fprintf(stderr, "fo err!\n");
    fprintf(stdout, "fo stdout!\n");
    fprintf(stderr, "fo err!\n");

    return 0;
}

[a@192 23]$ . / a.out
fo stdout!
fo stdout!
fo err!
fo err!
fo stdout!
fo err!
[a@192 23]$ . / a.out 1 > ok.log 2 > err.log			// 把正确 与错误 结果分别输出到两个文件里。
[a@192 23]$ ll
total 32
- rwxrwxr - x. 1 a a 8496 Apr 29 09:21 a.out
- rw - rw - r--. 1 a a   24 Apr 29 09 : 23 err.log
- rw - rw - r--. 1 a a   33 Apr 29 09 : 23 ok.log
- rw - rw - r--. 1 a a  349 Apr 29 09 : 21 test_stderr.c
[a@192 23]$ cat ok.log			//把正确 与错误的消息分开了。
fo stdout!
fo stdout!
fo stdout!
[a@192 23]$ cat err.log
fo err!
fo err!
fo err!


————————————————————————————————————————————————


			《 深入理解重定向 '>' 》

[a@192 23]$ ./a.out 1 > all.log 2 > &1				//把正确消息 与 错误消息都写到 all.log 文件中。
- rw - rw - r--. 1 a a   57 Apr 29 09:30 all.log
- rwxrwxr - x. 1 a a 8496 Apr 29 09 : 21 a.out
- rw - rw - r--. 1 a a  349 Apr 29 09 : 21 test_stderr.c
[a@192 23]$ cat all.log
fo err!
fo err!
fo err!
fo stdout!
fo stdout!
fo stdout!

注意：'>' 重定向会清空 原文件内容的。==> 类似 'w' 以写的方式打开
. / a.out 1 > all.log 2 > &1					//把 标准输出 重定向到 向all.log 里写 ， 把 2 号文件描述符 重定向 向 1标准输出的地址 (而此时标准输出是向 all.log里写)。
这里相当于 ==> 1 > all.log 2 > all.log		//变相的 把2 也指向了 all.log


————————————————————————————————————————————————


		< perror本质 >

int main()
{
    perror("error!!!");

    return 0;
}

[a@192 23]$ . / a.out
error!!!: Success
[a@192 23]$ . / a.out > log.txt		//想把标准错误 重定向到 log.txt，但是 log.txt：为空
error!!!: Success
[a@192 23]$ ll
total 32
- rwxrwxr - x. 1 a a 8408 Apr 29 09 : 44 a.out
- rw - rw - r--. 1 a a    0 Apr 29 09 : 44 log.txt
[a@192 23]$ cat log.txt
 log.txt：为空

结论：
perror("fopen");	//本质是向 2 号文件描述符打印

这里为什么用 fprintf 而不用 printf ?
printf();			//本质是向 1 号文件描述符打印


————————————————————————————————————————————————

			《 C++ 版重定向 》

#include <iostream>

int main()
{
    std::cout << "fo cout" << std::endl;
    std::cerr << "cerr" << std::endl;
}

[a@192 23]$ g++ std_stderr.cpp
[a@192 23]$ . / a.out
结果：
fo cout
cerr

	《 '>' 重定向：》
[a@192 23]$ . / a.out > log.txt
cerr
[a@192 23]$ cat log.txt
fo cout

本质：
cout ==> printf();
cerr ==> fprintf();


————————————————————————————————————————————————


————————————————————————————————————————————————
